home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
bit
/
src
/
forms
/
FORMS
/
symbols.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
8KB
|
278 lines
/*
* symbols.c
*
* This file is part of the basis of the Forms Library
*
* It contains the routine that draws all the symbols like arrows, etc.
* instead of labels. It can easily be extended with new symbols.
*
* Written by Mark Overmars
*
* Version 2.1 a
* Date: Oct 2, 1992
*/
#include <stdio.h>
#include <string.h>
#include "gl/gl.h"
#include "forms.h"
typedef struct {
char name[15]; /* its name */
void (*drawit)(int); /* the drawing routine */
int scalable; /* whether symbol can be scaled */
int empty; /* whether entry is used already */
} SYMBOL;
#define MAXSYMBOL 211
/* Maximal number of symbols in table. Only half of them are
used. Should be prime. */
static SYMBOL symbols[MAXSYMBOL]; /* The symbols */
static int symbnumb = -1; /* Their number */
static int h1(char name[])
/* The first hash function. */
{
if (name[0] == '\0') return 0;
else if (name[1] == '\0') return name[0] % MAXSYMBOL;
else if (name[2] == '\0') return (31*name[0]+name[1]) % MAXSYMBOL;
else return (71*name[0]+31*name[1]+name[2]) % MAXSYMBOL;
}
static int h2(char name[])
/* The second hash function. */
{
if (name[0] == '\0') return 0;
else if (name[1] == '\0') return (3*name[0]) % MAXSYMBOL;
else return (51*name[0]+3*name[1]) % MAXSYMBOL;
}
static int find(char name[])
/* Returns the index for the name or -1. */
{
int pos = h1(name), hh2 = h2(name);
while (strcmp(symbols[pos].name,name) != 0 && ! symbols[pos].empty)
pos = (pos + hh2) % MAXSYMBOL;
if (symbols[pos].empty) return -1; else return pos;
}
static int find_empty(char name[])
/* Returns the first empty index for the name (-1 when name exists). */
{
int pos = h1(name), hh2 = h2(name);
while (strcmp(symbols[pos].name,name) != 0 && ! symbols[pos].empty)
pos = (pos + hh2) % MAXSYMBOL;
if (symbols[pos].empty) return pos; else return -1;
}
/**************** The routines seen by the user *************************/
int fl_add_symbol(char name[], FL_DRAWPTR drawit, int scalable)
/* Adds a symbol to the system. Returns whether correct. */
{
int pos;
pos = find_empty(name);
if (pos == -1 || symbnumb > MAXSYMBOL / 2)
{fl_error("fl_add_symbol","Cannot add another symbol."); return FALSE;}
strcpy(symbols[pos].name,name);
symbols[pos].drawit = drawit;
symbols[pos].empty = FALSE;
symbols[pos].scalable = scalable;
symbnumb++;
return TRUE;
}
int fl_draw_symbol(char label[],float x,float y,float w,float h, int col)
/* Draws the symbol with the given label, returns whether it exists */
{
int pos , i, shift;
char str[50];
int rotangle = 0;
int equalscale = 0;
if (label[0] != '@') return FALSE;
if (label[1] == '#') {equalscale = 1; pos = 2;} else pos = 1;
shift = pos;
if (label[pos] >= '1' && label[pos] <= '9')
{
switch (label[pos])
{
case '9': rotangle = 450; break;
case '8': rotangle = 900; break;
case '7': rotangle = 1350; break;
case '4': rotangle = 1800; break;
case '1': rotangle = 2250; break;
case '2': rotangle = 2700; break;
case '3': rotangle = 3150; break;
}
shift = pos+1;
}
else if (label[pos] == '0')
{
rotangle = 1000*(label[pos+1]-'0') + 100*(label[pos+2]-'0') +
10*(label[pos+3]-'0');
shift = pos+4;
}
i = 0;
do str[i] = label[i+shift]; while (str[i++] != NULL);
pos = find(str);
if (pos == -1) return FALSE;
pushmatrix();
translate(x+w/2.0,y+h/2.0,0.0);
if (symbols[pos].scalable)
{
if (equalscale)
{ if (w<h) scale(0.4*w,0.4*w,1.0); else scale(0.4*h,0.4*h,1.0); }
else
scale(0.4*w,0.4*h,1.0);
rotate(rotangle,'z');
}
(symbols[pos].drawit)(col);
popmatrix();
return TRUE;
}
/******************** THE DEFAULT SYMBOLS ****************************/
/* Some help stuff */
#define BP bgnpolygon()
#define EP endpolygon()
#define BL bgnline();
#define EL endline();
#define BC bgnclosedline();
#define EC endclosedline();
static void circle(float x,float y,float r,int c)
{ fl_color(c); circf(x,y,r); fl_color(BLACK); circ(x,y,r); }
static void rectangle(float x1,float y1,float x2,float y2,int c)
{ fl_color(c); rectf(x1,y1,x2,y2); fl_color(BLACK); rect(x1,y1,x2,y2); }
static void vv(float x,float y)
{ float v[2] ; v[0] = x; v[1] = y; v2f(v);}
/* The drawing routines */
static void draw_arrow1(int col)
{
fl_color(col);
BP; vv(-0.8,-0.4); vv(-0.8,0.4); vv(0.3,0.4); vv(0.3,-0.4); EP;
BP; vv(0.0,0.8); vv(0.8,0.0); vv(0.0,-0.8); EP;
fl_color(BLACK);
BC; vv(-0.8,-0.4); vv(-0.8,0.4); vv(0.0,0.4); vv(0.0,0.8); vv(0.8,0.0);
vv(0.0,-0.8); vv(0.0,-0.4); EC;
}
static void draw_arrow2(int col)
{
fl_color(col);
BP; vv(-0.20,0.7); vv(0.50,0.0); vv(-0.20,-0.7); EP;
fl_color(BLACK);
BC; vv(-0.20,0.7); vv(0.50,0.0); vv(-0.20,-0.7); EC;
}
static void draw_arrow3(int col)
{
fl_color(col);
BP; vv(0.15,0.7); vv(0.85,0.0); vv(0.15,-0.7); EP;
BP; vv(-0.55,0.7); vv(0.15,0.0); vv(-0.55,-0.7); EP;
fl_color(BLACK);
BC; vv(0.15,0.7); vv(0.85,0.0); vv(0.15,-0.7); EC;
BC; vv(-0.55,0.7); vv(0.15,0.0); vv(-0.55,-0.7); EC;
}
static void draw_arrow01(int col)
{ rotate(1800,'z'); draw_arrow1(col); }
static void draw_arrow02(int col)
{ rotate(1800,'z'); draw_arrow2(col); }
static void draw_arrow03(int col)
{ rotate(1800,'z'); draw_arrow3(col); }
static void draw_doublearrow(int col)
{
fl_color(col);
BP; vv(-0.35,-0.4); vv(-0.35,0.4); vv(0.35,0.4); vv(0.35,-0.4); EP;
BP; vv(0.25,0.8); vv(0.85,0.0); vv(0.25,-0.8); EP;
BP; vv(-0.25,0.8); vv(-0.85,0.0); vv(-0.25,-0.8); EP;
fl_color(BLACK);
BC; vv(-0.25,0.4); vv(0.25,0.4); vv(0.25,0.8); vv(0.85,0.0);
vv(0.25,-0.8); vv(0.25,-0.4); vv(-0.25,-0.4); vv(-0.25,-0.8);
vv(-0.85,0.0); vv(-0.25,0.8); EC;
}
static void draw_arrow(int col)
{
fl_color(col);
BP; vv(0.65,0.1); vv(1.0,0.0); vv(0.65,-0.1); EP;
fl_color(BLACK);
BL; vv(-1.0,0.0); vv(0.65,0.0); EL;
BC; vv(0.65,0.1); vv(1.0,0.0); vv(0.65,-0.1); EC;
}
static void draw_returnarrow(int col)
{
fl_color(col);
BP; vv(-0.8,0.0); vv(-0.1,0.7); vv(-0.1,-0.7); EP;
fl_color(BLACK);
BC; vv(-0.8,0.0); vv(-0.1,0.7); vv(-0.1,-0.7); EC;
BL; vv(-0.1,0.0); vv(0.8,0.0); vv(0.8,0.7); EL;
}
static void draw_square(int col)
{ rectangle(-0.7,-0.7,0.7,0.7,col); }
static void draw_circle(int col)
{ circle(0.0,0.0,0.7,col); }
static void draw_line(int col)
{ fl_color(col); BL; vv(-1.0,0.0); vv(1.0,0.0); EL; }
static void draw_plus(int col)
{
fl_color(col);
BP; vv(-0.9,-0.15); vv(-0.9,0.15); vv(0.9,0.15); vv(0.9,-0.15); EP;
BP; vv(-0.15,-0.9); vv(-0.15,0.9); vv(0.15,0.9); vv(0.15,-0.9); EP;
fl_color(BLACK);
BC;
vv(-0.9,-0.15); vv(-0.9,0.15); vv(-0.15,0.15); vv(-0.15,0.9);
vv(0.15,0.9); vv(0.15,0.15); vv(0.9,0.15); vv(0.9,-0.15);
vv(0.15,-0.15); vv(0.15,-0.9); vv(-0.15,-0.9); vv(-0.15,-0.15);
EC;
}
static void draw_menu(int col)
{
fl_color(FL_RIGHT_BOUND_COL);
rectf(-0.5, -1.0, 0.8, 0.1);
rectf(-0.5, 0.45, 0.8, 0.85);
rectangle(-0.65, -0.85, 0.65, 0.25, col);
rectangle(-0.65, 0.6, 0.65, 1.0, col);
}
void fl_init_symbols()
/* initialises all the symbol entries and adds the default symbols */
{
int i;
symbnumb = 0;
for (i=0; i<MAXSYMBOL; i++) symbols[i].empty = TRUE;
fl_add_symbol("", draw_arrow1, 1);
fl_add_symbol("->", draw_arrow1, 1);
fl_add_symbol(">", draw_arrow2, 1);
fl_add_symbol(">>", draw_arrow3, 1);
fl_add_symbol("<-", draw_arrow01, 1);
fl_add_symbol("<", draw_arrow02, 1);
fl_add_symbol("<<", draw_arrow03, 1);
fl_add_symbol("<->", draw_doublearrow, 1);
fl_add_symbol("arrow", draw_arrow, 1);
fl_add_symbol("returnarrow", draw_returnarrow, 1);
fl_add_symbol("square", draw_square, 1);
fl_add_symbol("circle", draw_circle, 1);
fl_add_symbol("line", draw_line, 1);
fl_add_symbol("plus", draw_plus, 1);
fl_add_symbol("menu", draw_menu, 1);
}